/*
* Copyright (C) 2012-2014 qar
* License: http://www.gnu.org/licenses/gpl.html GPL version 2
*/

#ifndef OUTPUTSTREAM_H
#define OUTPUTSTREAM_H

#include <stdio.h>

#include <QtCore>

// Similar to qDebug(), but without quotes and optionally without newlines.
// Use qOut() or qErr() to instantiate.
class OutputStream
{
    QTextStream stream;
    bool addSpace;
    bool addNewline;
public:
    inline OutputStream(struct _IO_FILE *file) : stream(file), addSpace(true), addNewline(true) {
        stream.setCodec("UTF-8");
    }
    inline ~OutputStream() { if (addNewline) stream << endl; }

    inline OutputStream &noSpace() { addSpace = false; return *this; }
    inline OutputStream &noNewline() { addNewline = false; return *this; }

    inline OutputStream &space() { if (addSpace) stream << ' '; return *this; }

    inline OutputStream &operator<<(QChar t) { stream << t; return space(); }
    inline OutputStream &operator<<(QBool t) { stream << (bool(t != 0) ? "true" : "false"); return space(); }
    inline OutputStream &operator<<(bool t) { stream << (t ? "true" : "false"); return space(); }
    inline OutputStream &operator<<(char t) { stream << t; return space(); }
    inline OutputStream &operator<<(signed short t) { stream << t; return space(); }
    inline OutputStream &operator<<(unsigned short t) { stream << t; return space(); }
    inline OutputStream &operator<<(signed int t) { stream << t; return space(); }
    inline OutputStream &operator<<(unsigned int t) { stream << t; return space(); }
    inline OutputStream &operator<<(signed long t) { stream << t; return space(); }
    inline OutputStream &operator<<(unsigned long t) { stream << t; return space(); }
    inline OutputStream &operator<<(qint64 t) { stream << QString::number(t); return space(); }
    inline OutputStream &operator<<(quint64 t) { stream << QString::number(t); return space(); }
    inline OutputStream &operator<<(float t) { stream << t; return space(); }
    inline OutputStream &operator<<(double t) { stream << t; return space(); }
    inline OutputStream &operator<<(const char* t) { stream << QString::fromAscii(t); return space(); }
    inline OutputStream &operator<<(const QString & t) { stream << t; return space(); }
    inline OutputStream &operator<<(const QStringRef & t) { return operator<<(t.toString()); }
    inline OutputStream &operator<<(const QLatin1String &t) { stream << t.latin1(); return space(); }
    inline OutputStream &operator<<(const QByteArray & t) { stream  << t; return space(); }
    inline OutputStream &operator<<(const void * t) { stream << t; return space(); }
    inline OutputStream &operator<<(QTextStreamFunction f) { stream << f; return *this;	}
    inline OutputStream &operator<<(QTextStreamManipulator m) { stream << m; return *this; }
};
#define qOut() OutputStream(stdout)
#define qErr() OutputStream(stderr)
#define qWarn() OutputStream(stderr) << __FILE__ << __LINE__ << __FUNCTION__

#endif // OUTPUTSTREAM_H
